/* * Sun Public License Notice * * The contents of this file are subject to the Sun Public License * Version 1.0 (the "License"). You may not use this file except in * compliance with the License. A copy of the License is available at * http://www.sun.com/ * * The Original Code is Forte for Java, Community Edition. The Initial * Developer of the Original Code is Sun Microsystems, Inc. Portions * Copyright 1997-2000 Sun Microsystems, Inc. All Rights Reserved. */ package org.netbeans.modules.form; import org.openide.nodes.*; import java.awt.*; import java.beans.*; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; import java.util.ArrayList; /** BeanSupport is a utility class with various static methods supporting * operations with JavaBeans. * * @author Ian Formanek */ public class BeanSupport { // ----------------------------------------------------------------------------- // Private variables private static HashMap errorEmptyMap = new HashMap (3); /** * @associates Map */ private static HashMap valuesCache = new HashMap (30); /** * @associates Object */ private static HashMap instancesCache = new HashMap (30); // ----------------------------------------------------------------------------- // Public methods /** Utility method to create an instance of given class. Returns null on error. * @param beanClass the class to create inctance of * @return new instance of specified class or null if an error occured during instantiation */ public static Object createBeanInstance (Class beanClass) { try { return beanClass.newInstance (); } catch (IllegalAccessException e) { // problem => return null; } catch (InstantiationException e) { // problem => return null; } return null; } /** Utility method to obtain a BeanInfo of given JavaBean class. Returns null on error. * @param beanClass the class to obtain BeanInfo for * @return BeanInfo instance or null if an error occured or the BeanInfo cannot be found * throughout the BeanInfoSearchPath */ public static BeanInfo createBeanInfo (Class beanClass) { try { return org.openide.util.Utilities.getBeanInfo (beanClass); } catch (IntrospectionException e) { return null; } } /** Utility method to obtain an instance of specified beanClass. The instance is reused, and * thus should only be used to obtain info about settings of default instances of the specified class. * @param beanClass the class to create inctance of * @return instance of specified class or null if an error occured during instantiation */ public static Object getDefaultInstance (Class beanClass) { Object defInstance = instancesCache.get (beanClass); if (defInstance == null) { defInstance = createBeanInstance (beanClass); instancesCache.put (beanClass, defInstance); } return defInstance; } /** Utility method to obtain a default property values of specified JavaBean class. * The default values are property values immediately after the instance is created. * Because some AWT components initialize their properties only after the peer is * created, these are treated specially and default values for those properties * are provided explicitely (e.g. though the value of Font property of java.awt.Button * is null after an instance of Button is created, this method will return the * Font (Dialog, 12, PLAIN) as the default value). * * @param beanClass The Class of the JavaBean for which the default values are to be obtained * @returns Map containing pairs <PropertyName (String), value (Object)> * @see #getDefaultPropertyValue */ public static Map getDefaultPropertyValues (Class beanClass) { Map defValues = (Map) valuesCache.get (beanClass); if (defValues == null) { Object beanInstance = getDefaultInstance (beanClass); if (beanInstance == null) return errorEmptyMap; defValues = getPropertyValues (beanInstance); valuesCache.put (beanClass, defValues); } return defValues; } /** Utility method to obtain a default value of specified JavaBean class and property name. * The default values are property values immediately after the instance is created. * Because some AWT components initialize their properties only after the peer is * created, these are treated specially and default values for those properties * are provided explicitely (e.g. though the value of Font property of java.awt.Button * is null after an instance of Button is created, this method will return the * Font (Dialog, 12, PLAIN) as the default value). * * @param beanClass The Class of the JavaBean for which the default value is to be obtained * @param beanClass The name of the propertyn for which the default value is to be obtained * @returns The default property value for specified property on specified JavaBean class * @see #getDefaultPropertyValues */ public Object getDefaultPropertyValue (Class beanClass, String propertyName) { return getDefaultPropertyValues (beanClass).get (propertyName); } /** Utility method to obtain a current property values of given JavaBean instance. * Only the properties specified in bean info (if it exists) are provided. * * @returns Map containing pairs <PropertyName (String), value (Object)> */ public static Map getPropertyValues (Object beanInstance) { if (beanInstance == null) { return errorEmptyMap; } BeanInfo info = createBeanInfo (beanInstance.getClass ()); PropertyDescriptor[] properties = info.getPropertyDescriptors (); HashMap defaultValues = new HashMap (properties.length * 2); for (int i = 0; i < properties.length; i++) { Method readMethod = properties[i].getReadMethod (); if (readMethod != null) { try { Object value = readMethod.invoke (beanInstance, new Object [0]); if (value == null) value = getSpecialDefaultAWTValue (beanInstance, properties[i].getName ()); defaultValues.put (properties[i].getName (), value); } catch (Exception e) { // problem with reading property ==>> no default value if (FormEditor.getFormSettings ().getOutputLevel () != FormLoaderSettings.OUTPUT_MINIMUM) { // notifyPropertyException (beanInstance.getClass (), properties [i].getName (), "component", e, true); // NOI18N } } } else { // the property does not have plain read method if (properties[i] instanceof IndexedPropertyDescriptor) { // [PENDING] // Method indexedReadMethod = ((IndexedPropertyDescriptor)properties[i]).getIndexedReadMethod (); } } } return defaultValues; } /** Utility method to obtain an icon of specified JavaBean class and property name. * * @param iconType The icon type as defined in BeanInfo (BeanInfo.ICON_COLOR_16x16, ...) * @returns The icon of specified JavaBean or null if not defined */ public static Image getBeanIcon (Class beanClass, int iconType) { // [FUTURE: the icon should be obtained from the InstanceCookie somehow, and customizable by the user] BeanInfo bi = createBeanInfo (beanClass); if (bi != null) { return bi.getIcon (iconType); } return null; } /** A utility method that returns a class of event adapter for * specified listener. It works only on known listeners from java.awt.event. * Null is returned for unknown listeners. * @return class of an adapter for specified listener or null if * unknown/does not exist */ public static Class getAdapterForListener (Class listener) { if (java.awt.event.ComponentListener.class.equals (listener)) return java.awt.event.ComponentAdapter.class; else if (java.awt.event.ContainerListener.class.equals (listener)) return java.awt.event.ContainerAdapter.class; else if (java.awt.event.FocusListener.class.equals (listener)) return java.awt.event.FocusAdapter.class; else if (java.awt.event.KeyListener.class.equals (listener)) return java.awt.event.KeyAdapter.class; else if (java.awt.event.MouseListener.class.equals (listener)) return java.awt.event.MouseAdapter.class; else if (java.awt.event.MouseMotionListener.class.equals (listener)) return java.awt.event.MouseMotionAdapter.class; else if (java.awt.event.WindowListener.class.equals (listener)) return java.awt.event.WindowAdapter.class; else return null; // not found } public static Node.Property [] createEventsProperties (Object beanInstance) { BeanInfo beanInfo = createBeanInfo (beanInstance.getClass ()); EventSetDescriptor[] events = beanInfo.getEventSetDescriptors (); ArrayList eventsProps = new ArrayList (); for (int i = 0; i < events.length; i++) { } Node.Property[] np = new Node.Property [eventsProps.size ()]; eventsProps.toArray (np); return np; } // ----------------------------------------------------------------------------- // Private methods private static Object getSpecialDefaultAWTValue (Object beanObject, String propertyName) { if ((beanObject instanceof Frame) || (beanObject instanceof Dialog)) { if ("background".equals (propertyName)) // NOI18N return SystemColor.window; else if ("foreground".equals (propertyName)) // NOI18N return SystemColor.windowText; else if ("font".equals (propertyName)) // NOI18N return new Font ("Dialog", Font.PLAIN, 12); // NOI18N } if ((beanObject instanceof Label) || (beanObject instanceof Button) || (beanObject instanceof TextField) || (beanObject instanceof TextArea) || (beanObject instanceof Checkbox) || (beanObject instanceof Choice) || (beanObject instanceof List) || (beanObject instanceof Scrollbar) || (beanObject instanceof Panel) || (beanObject instanceof ScrollPane)) { if ("background".equals (propertyName)) // NOI18N return SystemColor.control; else if ("foreground".equals (propertyName)) // NOI18N return SystemColor.controlText; else if ("font".equals (propertyName)) // NOI18N return new Font ("Dialog", Font.PLAIN, 12); // NOI18N } return null; } } /* * Log * 14 Gandalf 1.13 1/13/00 Ian Formanek NOI18N #2 * 13 Gandalf 1.12 1/5/00 Ian Formanek NOI18N * 12 Gandalf 1.11 10/23/99 Ian Formanek NO SEMANTIC CHANGE - Sun * Microsystems Copyright in File Comment * 11 Gandalf 1.10 9/24/99 Ian Formanek getDefaultInstance * method added * 10 Gandalf 1.9 9/6/99 Ian Formanek Defaults for Window and * Dialog fixed, default colors for components are taken from SystemColor * rather than hardcoded colors (was Color.lightGray and Color.black) * 9 Gandalf 1.8 9/2/99 Ian Formanek Fixed bug 3696 - When * connection is copied and pasted into form, the initialization code of * the ConnectionSource component is not correctly generated. and 3695 - * Modified properties with null value are not restored correctly when a * form is reloaded. * 8 Gandalf 1.7 8/1/99 Ian Formanek OutputLevel changes * reflected * 7 Gandalf 1.6 7/30/99 Ian Formanek changed comment * 6 Gandalf 1.5 7/28/99 Ian Formanek Fixed bug 2147 - * horizontalAlignment property displays number instead of text. * 5 Gandalf 1.4 6/9/99 Ian Formanek ---- Package Change To * org.openide ---- * 4 Gandalf 1.3 5/30/99 Ian Formanek Removed * getPropertyEditor * 3 Gandalf 1.2 5/5/99 Ian Formanek * 2 Gandalf 1.1 5/4/99 Ian Formanek Package change * 1 Gandalf 1.0 4/29/99 Ian Formanek * $ */